﻿/*+========================================================
File:		GameObject.h
Sumary:		Hiện thực hóa các phương thức của lớp GameObject
========================================================+*/

#include "GameObject.h"

#pragma region Các phương thức của lớp CGameObject

CResourcesManager* CGameObject::m_pResourceManager = NULL;

CGameObject::CGameObject()
{
	m_pSprite = NULL;
	m_bIsLive = true;
}

CGameObject::CGameObject(D3DXVECTOR2 pos, int id, int typeID, int val1, int val2)
{
	m_pSprite = NULL;
	m_bIsLive = true;
	m_pos = pos;
	m_nTypeId = typeID;
	m_nId = id;
	m_nValue1 = val1;
	m_nValue2 = val2;
}

CGameObject::~CGameObject()
{
	if (m_pSprite)
		delete m_pSprite;
	if (m_pResourceManager)
		delete m_pResourceManager;
}

void CGameObject::Update(float timeFrame)
{
	if (!m_bIsLive)
		return;
	if (!m_pSprite)
	{
		OutputDebugString("[gameobject.cpp]Can not get Sprite to Update.");
		return;
	}
	m_pSprite->Update(timeFrame);
}

void CGameObject::Draw()
{
	if (!m_bIsLive)
		return;
	D3DXVECTOR2 pos;
	pos = CViewport::GetInstance()->TransformMatrix(m_pos);
	if (!m_pSprite)
	{
		OutputDebugString("[gameobject.cpp]Can not get Sprite to Draw - L55.\n");
		return;
	}
	m_pSprite->Draw(pos);
}

bool CGameObject::IsLive()
{
	return this->m_bIsLive;
}

bool CGameObject::Kill()
{
	m_bIsLive = false;
	return true;
}

Box CGameObject::GetBox()
{
	return m_box;
}

bool CGameObject::IsMoveableObject()
{
	return false;
}

void CGameObject::SetBoundBox(Box boundBox)
{
	this->m_box = boundBox;
}

int CGameObject::GetTypeId()
{
	return m_nTypeId;
}

D3DXVECTOR2 CGameObject::GetPos()
{
	return m_pos;
}

#pragma endregion

#pragma region Các phương thức của lớp CStaticObject

CStaticObject::CStaticObject(D3DXVECTOR2 pos, int id, int typeID)
	:CGameObject(pos, id, typeID)
{
	switch (typeID)
	{
	case ID_GRASS:
	case ID_GRASS_CAN_FALL:
		m_pTextureBox = m_pResourceManager->GetTexture(ID_TEXTURE_GROUND_BOX);
		break;
	case ID_WATER:
		m_pTextureBox = m_pResourceManager->GetTexture(ID_TEXTURE_WATER_BOX);
		break;
	case ID_SBOX:
		m_pTextureBox = m_pResourceManager->GetTexture(ID_TEXTURE_WATER_BOX);
		break;
	}
}

CStaticObject::~CStaticObject()
{

}

void CStaticObject::Update(float timeFrame)
{

}

void CStaticObject::Draw()
{
	if (!m_bIsLive)
		return;

	D3DXVECTOR2 pos = CViewport::GetInstance()->TransformMatrix(m_pos);

	//RECT rect;
	//rect.left = m_box.x - m_box.width / 2.0f;
	//rect.top = m_box.y + m_box.height / 2.0f;
	//rect.right = m_box.x + m_box.width / 2.0f;
	//rect.bottom = m_box.y - m_box.height / 2.0f;
	//D3DXVECTOR2 pos_box = CViewport::GetInstance()->TransformMatrix(D3DXVECTOR2(m_box.x + m_box.width / 2.0f, m_box.y - m_box.height / 2.0f));
	//m_pTextureBox->DrawRect(pos_box, rect);
}

#pragma endregion

#pragma region Các phương thức của lớp CMoveableObject

CMoveableObject::CMoveableObject(D3DXVECTOR2 pos, int id, int typeID, int val1, int val2) :
CGameObject(pos, id, typeID, val1, val2)
{
	m_a.x = 0.0f;
	m_a.y = 0.0f;
	m_v.x = 0.0f;
	m_v.y = 0.0f;

}

CMoveableObject::~CMoveableObject()
{

}

void CMoveableObject::Update(float timeFrame)
{
	if (!m_bIsLive)
		return;
	m_v += m_a * timeFrame;
	m_pos += m_v * timeFrame;
	if (!m_pSprite)
	{
		OutputDebugString("[gameobject.cpp]Can not get Sprite to Update.");
		return;
	}
	m_pSprite->Update(timeFrame);
	UpdateBox(timeFrame);
}

void CMoveableObject::UpdateBox(float timeFrame)
{
	m_box.x = m_pos.x - m_box.width / 2.0f;
	m_box.y = m_pos.y + m_box.height / 2.0f;
	m_box.vX = m_v.x;
	m_box.vY = m_v.y;
}

float CMoveableObject::CheckCollision(CGameObject* obj, float& normalx, float& normaly, float timeFrame)
{
	float timeCollision = timeFrame;
	Box myBox = this->GetBox();
	Box objBox = obj->GetBox();

	/*Box myBox(545.8f, 75.2f, 30.0f, 28.0f, 0.0f, -8.3f);
	Box objBox(576.0f, 52.0f, 128.0f, 20.0f, 0.0f, 0.0f);*/

	// Cố định objBox nếu objBox là đối tượng di chuyển.
	myBox.vX -= objBox.vX;
	myBox.vY -= objBox.vY;
	objBox.vX = 0;
	objBox.vY = 0;

	Box sweptBroadphaseBox = CCollision::GetSweptBroadphaseBox(myBox, timeFrame);

	if (CCollision::AABBCheck(sweptBroadphaseBox, objBox))
	{
		timeCollision = CCollision::SweepAABB(myBox, objBox, normalx, normaly, timeFrame);

		if (timeCollision == timeFrame && CCollision::AABBCheck(myBox, objBox))
			return 0;
	}

	return timeCollision;
}

void CMoveableObject::UpdateCollision(vector<CGameObject*> vecGameObjs, float deltaTime)
{

}


D3DXVECTOR2 CMoveableObject::GetVelocity()
{
	return m_v;
}

bool CMoveableObject::IsMoveableObject()
{
	return true;
}

#pragma endregion

#pragma region Các phương thức của lớp CTileObject

CTileObject::CTileObject(D3DXVECTOR2 pos, int id, int typeID, RECT r, int level)
	:CGameObject(pos, id, typeID)
{
	switch (level)
	{
	case ID_LEVEL1:
		m_pTexture = m_pResourceManager->GetTexture(ID_TEXTURE_MAP1_TILES);
		break;
	case ID_LEVEL2:
		m_pTexture = m_pResourceManager->GetTexture(ID_TEXTURE_MAP2_TILES);
		break;
	case ID_LEVEL3:
		m_pTexture = m_pResourceManager->GetTexture(ID_TEXTURE_MAP3_TILES);
		break;
	}
	m_SrcRect = r;
}

CTileObject::~CTileObject()
{
	if (m_pTexture)
		delete m_pTexture;
}

void CTileObject::Update(float timeFrame)
{

}

void CTileObject::Draw()
{
	if (!m_pTexture)
	{
		OutputDebugString("[gameobject.cpp]Can not get texture of Tile to Draw.");
		return;
	}
	D3DXVECTOR2 newPos = CViewport::GetInstance()->TransformMatrix(m_pos);
	D3DXVECTOR2 pos((int)newPos.x, (int)newPos.y);
	m_pTexture->DrawRect(pos, m_SrcRect);
}

#pragma endregion

